﻿using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text.Json;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using HostComputerPlatform.Models;
using HostComputerPlatform.Services;
using HostComputerPlatform.ViewModels;
using ModuleBase;
using Prism.Events;
using Prism.Ioc;
using System.IO;
using System.Reflection;
using Point = System.Windows.Point;
using ComboBox = System.Windows.Controls.ComboBox;
using Binding = System.Windows.Data.Binding;
using CheckBox = System.Windows.Controls.CheckBox;
using TextBox = System.Windows.Controls.TextBox;
using Brushes = System.Windows.Media.Brushes;
using MouseEventArgs = System.Windows.Input.MouseEventArgs;
using DragEventArgs = System.Windows.DragEventArgs;
using DragDropEffects = System.Windows.DragDropEffects;
using ListBox = System.Windows.Controls.ListBox;
using DataObject = System.Windows.DataObject;
using System.Collections.ObjectModel;
using Prism.Commands;
using System.Windows.Threading;
using Microsoft.Win32;
using HostComputerPlatform.Views;

namespace HostComputerPlatform.Views
{
    [AttributeUsage(AttributeTargets.Property)]
    public class DisplayPropertyAttribute : Attribute
    {
    }
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        private readonly IContainerProvider _containerProvider;
        private readonly CustomModuleManager _customModuleManager;
        private ModuleStateService _moduleStateService;
        private readonly MainWindowViewModel _viewModel;
        public event PropertyChangedEventHandler PropertyChanged;

        public MainWindow(IEventAggregator eventAggregator, MainWindowViewModel viewModel, IContainerProvider containerProvider, ModuleStateService moduleStateService, CustomModuleManager customModuleManager)
        {
            InitializeComponent();
            _containerProvider = containerProvider;
            _moduleStateService = moduleStateService;
            _customModuleManager = customModuleManager;
            _viewModel = viewModel;
            DataContext = _viewModel;
            _viewModel.PropertyChanged += OnViewModelPropertyChanged;
            Loaded += (s, e) => UpdateLogicTable();
            eventAggregator.GetEvent<UpdateTableEvent>().Subscribe(UpdateLogicTable, ThreadOption.UIThread);
        }

        private void UpdateLogicTable()
        {
            var grid = LogicTableGrid;
            while (grid.RowDefinitions.Count > 2)
            {
                grid.RowDefinitions.RemoveAt(2);
            }
            var childrenToRemove = grid.Children.Cast<UIElement>().Where(child => Grid.GetRow(child) >= 2).ToList();
            foreach (var child in childrenToRemove)
            {
                grid.Children.Remove(child);
            }
            grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
            grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });

            var viewModel = (MainWindowViewModel)DataContext;
            int totalRows = viewModel.LogicTableRows.Count;
            for (int i = 0; i < viewModel.LogicTableRows.Count; i++)
            {
                int currentRow = i;
                grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
                int rowIndex = i + 2;

                var rowContainer = new Grid();
                Grid.SetRow(rowContainer, rowIndex);
                Grid.SetColumnSpan(rowContainer, 4);

                var selection = new Border
                {
                    Background = i == viewModel.SelectedRowIndex ? Brushes.LightGoldenrodYellow : Brushes.Transparent,
                    IsHitTestVisible = false
                };
                rowContainer.Children.Add(selection);

                var clickArea = new Border
                {
                    Background = Brushes.Transparent,
                    IsHitTestVisible = true
                };
                clickArea.MouseLeftButtonDown += (s, e) =>
                {
                    viewModel.SelectedRowIndex = currentRow;
                    e.Handled = true;
                    UpdateLogicTable();
                };
                rowContainer.Children.Add(clickArea);
                grid.Children.Add(rowContainer);

                var rowData = viewModel.LogicTableRows[i];
                AddCell(grid, rowIndex, 0, (i + 1).ToString(), Brushes.Transparent);
                AddBranchColumn(grid, rowIndex, 1, rowData.SourceModule, rowData);
                AddConditionComboBox(grid, rowIndex, 2, rowData.TrueBranch, currentRow, totalRows, viewModel.SelectedRowIndex);
                AddConditionComboBox(grid, rowIndex, 3, rowData.FalseBranch, currentRow, totalRows, viewModel.SelectedRowIndex);
            }
        }

        private void AddCell(Grid parentGrid, int row, int column, string text, System.Windows.Media.Brush background)
        {
            var border = new Border
            {
                BorderBrush = Brushes.Black,
                BorderThickness = new Thickness(1),
                Background = background,
                Child = new TextBlock
                {
                    Text = text,
                    VerticalAlignment = VerticalAlignment.Center,
                    HorizontalAlignment = column == 0 ? System.Windows.HorizontalAlignment.Center : System.Windows.HorizontalAlignment.Left
                }
            };

            if (column == 0 || column == 1)
            {
                border.MouseLeftButtonDown += (s, e) =>
                {
                    _viewModel.SelectedRowIndex = row - 2; // 计算行索引
                    e.Handled = true;
                    UpdateLogicTable();
                };
            }

            Grid.SetRow(border, row);
            Grid.SetColumn(border, column);
            parentGrid.Children.Add(border);
        }
        private void AddBranchColumn(Grid grid, int row, int column, ObservableCollection<EditableItem> branchItems, LogicTableRow rowData)
        {
            var stackPanel = new StackPanel();

            // 1. 已添加实例用TextBlock显示
            foreach (var item in branchItems)
            {
                var itemGrid = new Grid();
                itemGrid.ColumnDefinitions.Add(new ColumnDefinition());
                itemGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto });

                // 用TextBlock显示实例名
                var module = _viewModel.InstantiatedModules.FirstOrDefault(m => m.Id == item.Content);
                var textBlock = new TextBlock
                {
                    Text = module?.DisplayName ?? "(未知实例)",
                    Margin = new Thickness(2),
                    VerticalAlignment = VerticalAlignment.Center,
                    Cursor = System.Windows.Input.Cursors.Hand
                };
                textBlock.MouseLeftButtonDown += (s, e) =>
                {
                    if (module != null)
                        _viewModel.SelectedModule = module;
                };
                Grid.SetColumn(textBlock, 0);
                itemGrid.Children.Add(textBlock);

                var deleteBtn = new System.Windows.Controls.Button
                {
                    Content = "×",
                    Width = 20,
                    Margin = new Thickness(1),
                    Background = Brushes.Red
                };
                deleteBtn.Click += (s, e) =>
                {
                    var result = System.Windows.MessageBox.Show("确定要删除该模块实例吗？", "确认删除", MessageBoxButton.YesNo, MessageBoxImage.Question);
                    if (result == MessageBoxResult.Yes)
                    {
                        _viewModel.RemoveModuleInstance(item.Content);
                        branchItems.Remove(item);
                        rowData.RefreshAfterDelete();
                        UpdateLogicTable();
                        Dispatcher.CurrentDispatcher.Invoke(() => { }, DispatcherPriority.ContextIdle);
                    }
                };
                Grid.SetColumn(deleteBtn, 1);
                itemGrid.Children.Add(deleteBtn);

                stackPanel.Children.Add(new Border
                {
                    BorderBrush = Brushes.Gray,
                    BorderThickness = new Thickness(0, 0, 0, 1),
                    Child = itemGrid
                });
            }

            // 2. 添加操作区域
            var addPanel = new StackPanel { Orientation = System.Windows.Controls.Orientation.Horizontal, Margin = new Thickness(5) };
            var typeComboBox = new ComboBox
            {
                ItemsSource = _viewModel.ModuleCategories,
                MinWidth = 80,
                Margin = new Thickness(0, 0, 5, 0)
            };
            var moduleComboBox = new ComboBox
            {
                MinWidth = 80,
                Margin = new Thickness(0, 0, 5, 0),
                IsEnabled = false
            };
            typeComboBox.SelectionChanged += (s, e) =>
            {
                if (typeComboBox.SelectedItem is string cat)
                {
                    moduleComboBox.ItemsSource = _viewModel.AvailableModules.Where(m => m.Category == cat).ToList();
                    moduleComboBox.DisplayMemberPath = "Name";
                    moduleComboBox.SelectedItem = null;
                    moduleComboBox.IsEnabled = true;
                }
            };
            var instanceComboBox = new ComboBox
            {
                MinWidth = 80,
                Margin = new Thickness(5, 0, 0, 0),
                DisplayMemberPath = "Name",
                SelectedValuePath = "Id",
                IsEnabled = false
            };
            // 2. addBtn 先声明
            System.Windows.Controls.Button addBtn = null;
            // 刷新实例下拉内容
            Action refreshInstanceComboBox = () => {
                if (typeComboBox.SelectedItem is string cat && moduleComboBox.SelectedItem is IModuleBase mod)
                {
                    var items = rowData.GetFilteredInstancesWithNewOption(_viewModel.InstantiatedModules).ToList();
                    if (items.Count == 0)
                    {
                        items.Add(new { Name = "新增实例", Id = "新增实例" });
                    }
                    instanceComboBox.ItemsSource = items;
                    instanceComboBox.IsEnabled = true;
                    instanceComboBox.SelectedValue = "新增实例";
                    rowData.SelectedInstanceId = "新增实例";
                }
                else
                {
                    instanceComboBox.ItemsSource = new[] { new { Name = "新增实例", Id = "新增实例" } };
                    instanceComboBox.IsEnabled = true;
                    instanceComboBox.SelectedValue = "新增实例";
                    rowData.SelectedInstanceId = "新增实例";
                }
                // 强制刷新按钮可用状态
                if (addBtn != null)
                    addBtn.IsEnabled = instanceComboBox.SelectedValue != null;
            };
            moduleComboBox.SelectionChanged += (s, e) => {
                // 新增：同步 rowData 的筛选条件
                if (typeComboBox.SelectedItem is string cat)
                    rowData.SelectedCategory = cat;
                if (moduleComboBox.SelectedItem is IModuleBase mod)
                    rowData.SelectedModuleType = mod.Name;
                refreshInstanceComboBox();
            };
            typeComboBox.SelectionChanged += (s, e) => { moduleComboBox.SelectedItem = null; refreshInstanceComboBox(); };
            // 初始刷新
            refreshInstanceComboBox();
            // 2. addBtn 先声明
            addBtn = new System.Windows.Controls.Button
            {
                Content = "+ 添加操作",
                Width = 80,
                IsEnabled = false
            };
            addBtn.Click += (s, e) => {
                if (typeComboBox.SelectedItem is string cat && moduleComboBox.SelectedItem is IModuleBase mod)
                {
                    // 同步 rowData 的筛选条件
                    rowData.SelectedCategory = cat;
                    rowData.SelectedModuleType = mod.Name;

                    IModuleBase template = null;
                    if (instanceComboBox.SelectedValue is string id && id != "新增实例")
                    {
                        // 选中已有实例，克隆其属性
                        template = _viewModel.InstantiatedModules.FirstOrDefault(m => m.Id == id);
                    }
                    else
                    {
                        // 选中"新增实例"，用模块模板
                        template = mod;
                    }

                    // 新建新实例，复制属性
                    var newModule = _viewModel._containerProvider.Resolve(template.GetType()) as IModuleBase;
                    newModule.TemplateName = template.TemplateName ?? template.Name;
                    newModule.Name = template.Name;
                    newModule.Category = template.Category;
                    newModule.Alias = template.Alias;
                    // 复制所有参数属性（如有）
                    foreach (var prop in template.GetType().GetProperties())
                    {
                        if (prop.CanWrite && prop.Name != "Id" && prop.Name != "Name" && prop.Name != "Category" && prop.Name != "Alias" && prop.Name != "TemplateName" && prop.Name != "Status")
                        {
                            prop.SetValue(newModule, prop.GetValue(template));
                        }
                    }
                    // Id自动生成
                    _viewModel.InstantiatedModules.Add(newModule);
                    rowData.SourceModule.Add(new EditableItem(item => rowData.SourceModule.Remove(item))
                    {
                        Content = newModule.Id
                    });
                    _viewModel.SelectedModule = newModule;
                    UpdateLogicTable();
                    // 添加操作后刷新实例下拉框
                    refreshInstanceComboBox();
                }
            };
            addPanel.Children.Add(typeComboBox);
            addPanel.Children.Add(moduleComboBox);
            addPanel.Children.Add(instanceComboBox);
            addPanel.Children.Add(addBtn);
            stackPanel.Children.Add(addPanel);

            var border = new Border
            {
                BorderBrush = Brushes.Black,
                BorderThickness = new Thickness(1),
                Child = stackPanel
            };
            Grid.SetRow(border, row);
            Grid.SetColumn(border, column);
            grid.Children.Add(border);
        }
        private void AddConditionComboBox(Grid parentGrid, int row, int column, ObservableCollection<EditableItem> items, int currentRow, int totalRows, int selectedRowIndex)
        {
            var border = new Border
            {
                BorderBrush = Brushes.Black,
                BorderThickness = new Thickness(1),
                Background = Brushes.Transparent,
                VerticalAlignment = VerticalAlignment.Stretch
            };

            var mainGrid = new Grid();
            mainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });

            var contentContainer = new Grid
            {
                VerticalAlignment = VerticalAlignment.Center
            };
            Grid.SetRow(contentContainer, 1);
            mainGrid.Children.Add(contentContainer);

            var horizontalPanel = new StackPanel
            {
                Orientation = System.Windows.Controls.Orientation.Horizontal,
                HorizontalAlignment = System.Windows.HorizontalAlignment.Left,
                VerticalAlignment = VerticalAlignment.Center
            };
            contentContainer.Children.Add(horizontalPanel);

            var availableOptions = new List<string> { "无" };
            availableOptions.AddRange(Enumerable.Range(1, totalRows).Select(x => x.ToString()));

            var comboBox = new ComboBox
            {
                Margin = new Thickness(10, 0, 10, 0),
                MinWidth = 80,
                VerticalAlignment = VerticalAlignment.Center,
                ItemsSource = availableOptions,
                SelectedItem = items.FirstOrDefault()?.Content ?? "无"
            };

            comboBox.SelectionChanged += (s, e) =>
            {
                if (comboBox.SelectedItem != null && !items.Any())
                {
                    items.Add(new EditableItem(item => items.Remove(item)) { Content = comboBox.SelectedItem.ToString() });
                }
            };

            horizontalPanel.Children.Add(comboBox);

            if (currentRow == selectedRowIndex)
            {
                var locateButton = new System.Windows.Controls.Button
                {
                    Content = "定位",
                    MinWidth = 40,
                    VerticalAlignment = VerticalAlignment.Center,
                    IsEnabled = comboBox.SelectedItem != null && comboBox.SelectedItem.ToString() != "无",
                    Command = new DelegateCommand(() =>
                    {
                        if (comboBox.SelectedItem != null && comboBox.SelectedItem.ToString() != "无")
                        {
                            int targetRow = int.Parse(comboBox.SelectedItem.ToString()) - 1;
                            _viewModel.SelectedRowIndex = targetRow;

                            var scrollViewer = FindVisualParent<ScrollViewer>(parentGrid);
                            if (scrollViewer != null)
                            {
                                var targetElement = parentGrid.Children
                                    .Cast<UIElement>()
                                    .FirstOrDefault(c => Grid.GetRow(c) == targetRow + 2);

                                if (targetElement != null)
                                {
                                    GeneralTransform transform = targetElement.TransformToAncestor(scrollViewer);
                                    Point position = transform.Transform(new Point(0, 0));

                                    scrollViewer.ScrollToVerticalOffset(position.Y);
                                }
                            }

                            UpdateLogicTable();
                        }
                    })
                };

                comboBox.SelectionChanged += (s, e) =>
                {
                    locateButton.IsEnabled = comboBox.SelectedItem != null && comboBox.SelectedItem.ToString() != "无";
                };

                horizontalPanel.Children.Add(locateButton);
            }

            border.Child = mainGrid;

            border.MouseLeftButtonDown += (s, e) =>
            {
                _viewModel.SelectedRowIndex = row - 2;
                e.Handled = true;
                UpdateLogicTable();
            };

            Grid.SetRow(border, row);
            Grid.SetColumn(border, column);
            parentGrid.Children.Add(border);
        }
        private static T FindVisualParent<T>(DependencyObject child) where T : DependencyObject
        {
            while (child != null && !(child is T))
            {
                child = VisualTreeHelper.GetParent(child);
            }
            return child as T;
        }

        private void OnViewModelPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == nameof(MainWindowViewModel.SelectedModule))
            {
                UpdatePropertyPanel(_viewModel.SelectedModule);
            }
        }
        private void UpdatePropertyPanel(IModuleBase module)
        {
            PropertyPanel.Children.Clear();

            if (module != null)
            {
                var nameTextBlock = new TextBlock
                {
                    Margin = new Thickness(10, 5, 10, 5),
                    FontSize = 16,
                    FontWeight = FontWeights.Bold,
                    Text = module.Name,
                    ToolTip = module.Description
                };
                PropertyPanel.Children.Add(nameTextBlock);

                // 新增：别名属性
                var aliasLabel = new TextBlock
                {
                    Margin = new Thickness(10, 5, 10, 0),
                    Text = "别名"
                };
                PropertyPanel.Children.Add(aliasLabel);
                var aliasTextBox = new TextBox
                {
                    Margin = new Thickness(10, 0, 10, 5),
                    Text = module.Alias
                };
                aliasTextBox.TextChanged += (s, e) =>
                {
                    module.Alias = aliasTextBox.Text;
                    // 触发属性变更，刷新界面
                    OnViewModelPropertyChanged(this, new PropertyChangedEventArgs(nameof(_viewModel.SelectedModule)));
                    UpdateLogicTable();
                    // 新增：强制刷新所有行的实例下拉框
                    // 遍历所有流程行，刷新实例下拉框
                    foreach (var row in _viewModel.LogicTableRows)
                    {
                        // 只要调用UpdateLogicTable即可，所有下拉框会重建
                        // 如果有更细粒度的刷新方法，可在此调用
                    }
                };
                PropertyPanel.Children.Add(aliasTextBox);

                var properties = module.GetProperties();
                foreach (var property in properties)
                {
                    var propertyNameTextBlock = new TextBlock
                    {
                        Margin = new Thickness(10, 5, 10, 0),
                        Text = property.Key
                    };
                    PropertyPanel.Children.Add(propertyNameTextBlock);

                    var propertyName = GetPropertyNameByDisplayName(module, property.Key);

                    if (module.PropertyOptions != null && module.PropertyOptions.ContainsKey(property.Key))
                    {
                        var comboBox = new ComboBox
                        {
                            Margin = new Thickness(10, 0, 10, 5),
                            ItemsSource = module.PropertyOptions[property.Key],
                            SelectedItem = property.Value
                        };

                        var binding = new Binding(propertyName)
                        {
                            Source = module,
                            UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
                            Mode = BindingMode.TwoWay
                        };
                        comboBox.SetBinding(ComboBox.SelectedItemProperty, binding);

                        PropertyPanel.Children.Add(comboBox);
                    }
                    else if (property.Value is bool)
                    {
                        var checkBox = new CheckBox
                        {
                            Margin = new Thickness(10, 0, 10, 5),
                            IsChecked = (bool)property.Value
                        };

                        var binding = new Binding(propertyName)
                        {
                            Source = module,
                            UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
                            Mode = BindingMode.TwoWay
                        };
                        checkBox.SetBinding(CheckBox.IsCheckedProperty, binding);

                        PropertyPanel.Children.Add(checkBox);
                    }
                    else
                    {
                        var propertyValueTextBox = new TextBox
                        {
                            Margin = new Thickness(10, 0, 10, 5),
                            Text = property.Value?.ToString()
                        };

                        var binding = new Binding(propertyName)
                        {
                            Source = module,
                            UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
                            Mode = BindingMode.TwoWay
                        };
                        propertyValueTextBox.SetBinding(TextBox.TextProperty, binding);

                        PropertyPanel.Children.Add(propertyValueTextBox);
                    }
                }
            }
        }
        private string GetPropertyNameByDisplayName(IModuleBase module, string displayName)
        {
            if (module is ModuleBase.ModuleBase baseModule && baseModule.DisplayNameToPropertyNameMap.ContainsKey(displayName))
            {
                return baseModule.DisplayNameToPropertyNameMap[displayName];
            }

            Debug.WriteLine($"未找到与显示名称匹配的属性: {displayName}");
            return displayName;
        }
        private async void ExecuteButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 调用 ViewModel 中的 StartExecutionFlow 方法来启动执行流程
                await _viewModel.StartExecutionFlow();
            }
            catch (System.Exception ex)
            {
            }
        }
        private void PauseButton_Click(object sender, RoutedEventArgs e)
        {
            _viewModel.ExecutionFlowService.PauseExecution();
        }
        private void StopButton_Click(object sender, RoutedEventArgs e)
        {
            _moduleStateService.StopAllModules();
            _viewModel.ExecutionFlowService.StopExecution();
        }
        private void ResumeButton_Click(object sender, RoutedEventArgs e)
        {
            _viewModel.ExecutionFlowService.ResumeExecution();
        }
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        private static T FindParent<T>(DependencyObject child) where T : class
        {
            var parentObject = VisualTreeHelper.GetParent(child);
            if (parentObject == null) return null;

            if (parentObject is T parent)
            {
                return parent;
            }

            return FindParent<T>(parentObject);
        }
        public static class FocusExtension
        {
            public static bool GetIsFocused(DependencyObject obj)
            {
                return (bool)obj.GetValue(IsFocusedProperty);
            }

            public static void SetIsFocused(DependencyObject obj, bool value)
            {
                obj.SetValue(IsFocusedProperty, value);
            }

            public static readonly DependencyProperty IsFocusedProperty =
                DependencyProperty.RegisterAttached(
                    "IsFocused", typeof(bool), typeof(FocusExtension),
                    new UIPropertyMetadata(false, OnIsFocusedPropertyChanged));

            private static void OnIsFocusedPropertyChanged(
                DependencyObject d,
                DependencyPropertyChangedEventArgs e)
            {
                var uie = (UIElement)d;
                //if ((bool)e.NewValue)
                //{
                //    uie.Focus(); // Don't care about false values.
                //}
                uie.Focus();
            }
        }
        private void MsgTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            MsgTextBox.ScrollToEnd();
        }

        private void AvailableModulesList_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {

        }

        private void ProgramFlowChart_Click(object sender, RoutedEventArgs e)
        {
            var openFileDialog = new Microsoft.Win32.OpenFileDialog();
            openFileDialog.Filter = "PNG图片|*.png";
            if (openFileDialog.ShowDialog() == true)
            {
                // 设置ViewModel的图片路径
                if (DataContext is HostComputerPlatform.ViewModels.MainWindowViewModel vm)
                {
                    vm.ProgramFlowChartImagePath = openFileDialog.FileName;
                }
            }
        }

        // 新增：执行逻辑表删除按钮事件
        private void DeleteLogicTableRow_Click(object sender, RoutedEventArgs e)
        {
            var result = System.Windows.MessageBox.Show("确定要删除当前选中的流程行吗？", "确认删除", MessageBoxButton.YesNo, MessageBoxImage.Question);
            if (result == MessageBoxResult.Yes)
            {
                _viewModel.OperateCommand.Execute("删除");
            }
        }

        private void OpenVariableLibrary_Click(object sender, RoutedEventArgs e)
        {
            var dlg = new VariableLibraryWindow(_viewModel.VariableLibrary)
            {
                Owner = this
            };
            if (dlg.ShowDialog() == true)
            {
                // 保存到项目文件夹或指定路径
                string folder = Directory.GetCurrentDirectory();
                string varPath = System.IO.Path.Combine(folder, "variables.json");
                _viewModel.SaveVariableLibrary(varPath);
                System.Windows.MessageBox.Show("变量库已保存", "提示", MessageBoxButton.OK, System.Windows.MessageBoxImage.Information);
            }
        }

        // 恢复模块库隐藏/展开按钮事件
        private void ToggleModuleLibBtn_Click(object sender, RoutedEventArgs e)
        {
            if (ModuleLibCol.Width.Value > 0)
            {
                // 收缩
                ModuleLibCol.Width = new GridLength(0);
                ModuleLibPanel.Visibility = Visibility.Collapsed;
                ToggleModuleLibBtn.Content = System.Windows.Markup.XamlReader.Parse("<TextBlock xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">&gt;</TextBlock>");
            }
            else
            {
                // 展开
                ModuleLibCol.Width = new GridLength(250);
                ModuleLibPanel.Visibility = Visibility.Visible;
                ToggleModuleLibBtn.Content = System.Windows.Markup.XamlReader.Parse("<TextBlock xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">&lt;</TextBlock>");
            }
        }
    }
}